home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /* idebug.c */
- /* Debugging support for Ghostscript interpreter */
- #include "string_.h"
- #include "ghost.h"
- #include "dict.h"
- #include "iname.h"
- #include "iutil.h"
- #include "ostack.h" /* for opdef.h */
- #include "opdef.h"
- #include "packed.h"
- #include "store.h" /* for make_oper for opdef.h */
-
- /* Forward references */
- void debug_print_string(P2(const byte *, ushort));
- void debug_print_ref(P1(const ref *));
-
- #define debug_print_name(pnref)\
- debug_print_string((pnref)->value.pname->string_bytes,\
- (pnref)->value.pname->string_size)
-
- /* Table of type name strings */
- static const char *type_strings[] = { type_print_strings };
-
- /* Print a ref */
- void
- debug_print_full_ref(const ref *pref)
- { unsigned size = r_size(pref);
- ref nref;
- dprintf1("(%x)", r_type_attrs(pref));
- switch ( r_type(pref) )
- {
- case t_array:
- dprintf2("array(%u)0x%lx", size, (ulong)pref->value.refs); break;
- case t_boolean:
- dprintf1("boolean %x", pref->value.index); break;
- case t_condition:
- dprintf1("condition 0x%lx", (ulong)pref->value.pcond); break;
- case t_device:
- dprintf1("device 0x%lx", (ulong)pref->value.pdevice); break;
- case t_dictionary:
- dprintf3("dict(%u/%u)0x%lx",
- dict_length(pref), dict_maxlength(pref),
- (ulong)pref->value.pdict);
- break;
- case t_file:
- dprintf1("file 0x%lx", (ulong)pref->value.pfile); break;
- case t_gstate:
- dprintf1("gstate 0x%lx", (ulong)pref->value.pgstate); break;
- case t_integer: dprintf1("int %ld", pref->value.intval); break;
- case t_lock:
- dprintf1("lock 0x%lx", (ulong)pref->value.plock); break;
- case t_mark: dprintf("mark"); break;
- case t_mixedarray:
- dprintf2("mixed packedarray(%u)0x%lx", size,
- (ulong)pref->value.packed); break;
- case t_name:
- dprintf2("name(0x%lx#%x)", (ulong)pref->value.pname,
- name_index(pref));
- debug_print_name(pref);
- break;
- case t_null: dprintf("null"); break;
- case t_oparray:
- dprintf1("op_array(0x%x)", size);
- name_index_ref(op_array_nx_table[size - op_def_count], &nref);
- debug_print_name(&nref);
- break;
- case t_operator:
- dprintf1("op(0x%x", size);
- if ( size )
- dprintf1(":%s", (const char *)(op_def_table[size]->oname + 1));
- dprintf1(")0x%lx", (ulong)pref->value.opproc);
- break;
- case t_real: dprintf1("real %f", pref->value.realval); break;
- case t_shortarray:
- dprintf2("short packedarray(%u)0x%lx", size,
- (ulong)pref->value.packed); break;
- case t_string:
- dprintf2("string(%u)0x%lx", size, (ulong)pref->value.bytes); break;
- default: dprintf1("type 0x%x", r_type(pref));
- }
- }
- void
- debug_print_packed_ref(const ref_packed *pref)
- { ushort elt = *pref;
- ref nref;
- switch ( elt >> packed_type_shift )
- {
- case pt_executable_operator:
- dprintf("<op_name>");
- elt &= packed_int_mask;
- op_index_ref(elt, &nref);
- debug_print_ref(&nref);
- break;
- case pt_integer:
- dprintf1("<int> %d", (int)(elt & packed_int_mask) + packed_min_intval);
- break;
- case pt_literal_name: case pt_literal_name+1:
- dprintf("<lit_name>"); elt &= packed_max_name_index; goto ptn;
- case pt_executable_name: case pt_executable_name+1:
- dprintf("<exec_name>"); elt &= packed_max_name_index;
- ptn: name_index_ref(elt, &nref);
- dprintf2("(0x%lx#%x)", (ulong)nref.value.pname, elt);
- debug_print_name(&nref);
- break;
- }
- }
- void
- debug_print_ref(const ref *pref)
- { if ( r_is_packed(pref) )
- debug_print_packed_ref((const ref_packed *)pref);
- else
- debug_print_full_ref(pref);
- fflush(dstderr);
- }
-
- /* Print a string */
- void
- debug_print_string(const byte *chrs, ushort len)
- { ushort i;
- for ( i = 0; i < len; i++ )
- dputc(chrs[i]);
- fflush(dstderr);
- }
-
- /* Dump one ref */
- void
- debug_dump_one_ref(const ref *p)
- { uint attrs = r_type_attrs(p);
- uint type = r_type(p);
- static const char *as = attr_print_string;
- const char *ap = as;
- #define buf_size 30
- char buf[buf_size + 1];
- uint plen;
- if ( type >= tx_next_index )
- dprintf1("0x%02x?? ", type);
- else if ( type >= t_next_index )
- dprintf("opr* ");
- else
- dprintf1("%s ", type_strings[type]);
- for ( ; *ap; ap++, attrs >>= 1 )
- if ( *ap != '.' )
- dputc(((attrs & 1) ? *ap : '-'));
- dprintf2(" 0x%04x 0x%08lx", r_size(p), *(const ulong *)&p->value);
- if ( obj_cvs(p, (byte *)buf, countof(buf) - 1, &plen) >= 0 &&
- ((buf[plen] = 0), strcmp(buf, "--nostringval--"))
- )
- dprintf1(" = %s", buf);
- fflush(dstderr);
- }
-
- /* Dump a region of memory containing refs */
- void
- debug_dump_refs(const ref *from, uint size, const char *msg)
- { const ref *p = from;
- uint count = size;
- if ( size && msg )
- dprintf2("%s at 0x%lx:\n", msg, (ulong)from);
- while ( count-- )
- { dprintf2("..%04x: 0x%02x ", (uint)p & 0xffff, r_type(p));
- debug_dump_one_ref(p);
- dputc('\n');
- p++;
- }
- }
-
- /* Dump a region of memory */
- void
- debug_dump_bytes(const byte *from, const byte *to, const char *msg)
- { const byte *p = from;
- if ( from < to && msg )
- dprintf1("%s:\n", msg);
- while ( p != to )
- { const byte *q = min(p + 16, to);
- dprintf1("%lx:", (ulong)p);
- while ( p != q ) dprintf1(" %02x", *p++);
- dputc('\n');
- }
- }
-
- /* Dump an array. */
- void
- debug_dump_array(const ref *array)
- { const ref_packed *pp;
- unsigned int type = r_type(array);
- uint len;
-
- switch (type)
- {
- default:
- dprintf2 ("%s at 0x%lx isn't an array.\n",
- (type < countof(type_strings) ?
- type_strings[type] : "????"),
- (ulong)array);
- return;
- case t_oparray:
- /* This isn't really an array, but we'd like to see */
- /* its contents anyway. */
- debug_dump_array(op_array_table.value.refs + op_index(array) -
- op_def_count);
- return;
- case t_array:
- case t_mixedarray:
- case t_shortarray:
- ;
- }
-
- /* This "packed" loop works for all array-types. */
- for ( len = r_size (array), pp = array->value.packed;
- len > 0;
- len--, pp = packed_next(pp))
- { ref temp;
- packed_get(pp, &temp);
- dprintf3("..%04x%c 0x%02x ",
- (uint)pp & 0xffff,
- ((r_is_packed(pp)) ? '*' : ':'),
- r_type(&temp));
- debug_dump_one_ref(&temp);
- dputc ('\n');
- }
- }
-